﻿#ifndef GY_IDTABLEVIEW_H
#define GY_IDTABLEVIEW_H

#include "GY_ControlLibrary_global.h"
#include <QTableView>
#include <QStandardItem>
#include <QStandardItemModel>
#include <QMouseEvent>

class CustomFilterModule;
class GY_CONTROLLIBRARY_EXPORT GY_IdTableView : public QTableView
{
    Q_OBJECT
public:
    /**
     * @brief The TableDataType enum
     * 表格数据类型枚举
     */
    enum TableDataType
    {
        //!显示数据
        DisplayData=Qt::DisplayRole,
        //!传输数据
        TransferData=Qt::UserRole+1,
        //!行Id数据
        RowIdData,
    };
protected:
    //!数据信息Map
    QMap<QVariant,QList<QStandardItem*>> m_RowDataInfoMap;
    //!最后一次选择的Item
    QStandardItem * m_pLastSelectItme;
    //!数据Module
    QStandardItemModel* m_pModel;
    //! 自定义过滤组件
    CustomFilterModule* m_pFilter;
public:
    explicit GY_IdTableView(QWidget *parent = nullptr);

    /**
     * @brief 扩展标准数据模型
     * @param pModel
     * @param parent
     * @date 2024-4-11 为GY_CellMergeAndDragTable增加
     */
    GY_IdTableView(QStandardItemModel* pModel, QWidget *parent = nullptr);

//-------------------------列编辑接口--------------------------------
    /**
    * @brief setColumnCount 设置列数
    * @param columnCount 添加的列数
    */
    void setColumnCount(const int columnCount);
    /**
    * @brief addColumn 添加空白列
    * @param columnName 添加的列名
    */
    void addColumn(const QString &columnNmae);
    /**
    * @brief insterColumn 插入列
    * @param index 插入在第几列
    * @param columnName 插入的列名
    * @return 返回插入列是否成功
    */
    bool insterColumn(const int index, const QString &columnName);
    /**
    * @brief deleteColumn 删除列
    * @param index 删除的第几列
    * @return 返回删除列是否成功
    */
    bool deleteColumn(const int index);
    /**
    * @brief setColumnHeadName  设置列头名称
    * @param nameList  要修改的列名集
    */
    void setColumnHeadName(const QStringList &nameList);
    /**
    * @brief setColumnHeadName  修改某一列列名
    * @param index  要修改名字在第几列
    * @param headName  要修改成的名字
    */
    void setColumnHeadName(const int index,const QString &headName);
    //-------------------------行编辑接口--------------------------------
    /**
    * @brief addRowData 添加行
    * @param rowId 添加的行Id
    * @param rowData 添加的行数据
    * @return返回是否添加成功
    */
    virtual bool addRowData(const QVariant& rowId, const QVector<QVariant> &rowData);
    /**
     * @brief insertRowData 插入行数据
     * @param rowIndex 插入行索引
     * @param rowId 插入的行Id
     * @param rowData 插入的行数据
     * @return 是否插入成功
     */
    bool insertRowData(const int rowIndex,const QVariant& rowId, const QVector<QVariant> &rowData);
    /**
     * @brief deleteRow  删除指定行
     * @param rowId 删除行Id
     * @return 返回删除是否成功
     */
    bool deleteRow(const QVariant& rowId);
    /**
     * @brief setRowData  修改行数据
     * @param rowId 行Id
     * @param rowData  待修改的数据
     * @return 是否修改成功
     */
    bool setRowData(const QVariant& rowId, const QVector<QVariant>&rowData);
    /**
     * @brief getRowData 获取行数据
     * @param rowId 行ID
     * @return 返回获取的行数据
     */
    QVector<QVariant> getRowData(const QVariant& rowId);
    /**
     * @brief setRowEnabled 设置行交互状态
     * @param rowId  行ID
     * @param isEnabled 是否可交互
     * @return 返回设置是否成功
     */
    bool setRowEnabled(const QVariant &rowId, const bool isEnabled);
    /**
     * @brief setRowEditabled 设置行编辑状态
     * @param rowId 行ID
     * @param isEditabled 是否可编辑
     * @return 返回设置是否成功
     */
    bool setRowEditabled(const QVariant &rowId, const bool isEditabled);
    /**
     * @brief setTextCenter 设置文字居中显示
     * @param rowId 索引第几行
     * @return 返回设置是否成功
     */
    bool setTextCenter(const QVariant rowId);
    /**
     * @brief getRowIndex 获取行索引
     * @param rowId 行Id
     * @return 行索引
     */
    int getRowIndex(const QVariant &rowId);
    //-------------------------单元格编辑接口--------------------------------
    /**
     * @brief setCellColor 修改item背景颜色
     * @param rowId 行id
     * @param columnIndex 列
     * @param color 颜色
     * @return 是否修改成功
     */
    bool setCellColor(const QVariant &rowId, const int columnIndex, const QColor &color);
    /**
     * @brief setCellData  修改单元格数据
     * @param rowId 修改行Id
     * @param columnIndex  修改列索引
     * @param cellData  要修改的数据
     * @param role 修改的数据类型
     * @return 是否修改成功
     */
    bool setCellData(const QVariant& rowId, const int columnIndex, const QVariant &cellData, int role=TableDataType::TransferData);
    /**
     * @brief setCellText 设置单元格文字
     * @param rowId 行ID
     * @param columnIndex 列索引
     * @param displayText 显示文字
     * @return 是否设置成功
     */
    bool setCellText(const QVariant& rowId, const int columnIndex,const QString& displayText);
    /**
     * @brief getCellData
     * @param rowId 行ID
     * @param columnIndex 列索引
     * @param role 获取的数据类型
     * @return 单元格数据
     */
    QVariant getCellData(const QVariant& rowId, const int columnIndex,int role=TableDataType::TransferData);
    /**
     * @brief getCellText 获取单元格文字
     * @param rowId 行ID
     * @param columnIndex 列索引
     * @return 单元格文字
     */
    QString getCellText(const QVariant& rowId, const int columnIndex);
    /**
     * @brief setCellEnabled 设置行交互状态
     * @param rowId  行ID
     * @param columnIndex 列索引
     * @param isEnabled 是否可交互
     * @return 返回设置是否成功
     */
    bool setCellEnabled(const QVariant &rowId, const int columnIndex, const bool isEnabled);
    /**
     * @brief setCellEditabled 设置行编辑状态
     * @param rowId  行ID
     * @param columnIndex 列索引
     * @param isEditabled 是否可编辑
     * @return 返回设置是否成功
     */
    bool setCellEditabled(const QVariant &rowId, const int columnIndex, const bool isEditabled);
    //-----------------------------选择接口----------------------------
    /**
     * @brief getSelectRowIndex  获取选择行Id
     * @return  多选下返回选中的行Id
     */
    QVariant getSelectRowId();
    /**
     * @brief setSelectRow 设置选择行
     * @param rowId 设置选择的ID
     * @return 是否设置成功
     */
    bool  setSelectRow(const QVariant &rowId);
    /**
     * @brief setSelectCell 设置选中单元格
     * @param rowId 设置单元格的行ID
     * @param columnIndex 设置单元格的列索引
     * @return 是否设置成功
     */
    bool  setSelectCell(const QVariant &rowId, const int columnIndex);
    //-------------------------其他接口--------------------------------
    /**
     * @brief clearData 清除所有数据
     */
    void clearData();

    //-------------------------搜索过滤接口--------------------------------
    /**
     * @brief setFilterRegExp 设置过滤正则表达式
     * @param searchText 搜索过滤文本
     */
    void setFilterRegExp(const QString &searchText);

    /**
     * @brief setFilterColumn 设置过滤列
     * @param column
     */
    void setFilterColumn(const int column);

    /**
     * @brief findTargetRow 模糊匹配目标行
     * @param index 传入表头下标 与 要搜索的字段
     * @param 最终由表格展示
     */
    void findTargetRow(const QMap<int,QString> &dataMap);
    /**
     * @brief isAllAccordWith 辅助模糊匹配函数
     * 判断行数据是否满足所有条件
     */
    bool isAllAccordWith(const int &row, const QMap<int, QString> &colInfoMap, const QStringList &conditionList);
signals:
    /**
     * @brief selectRowChangeSignal 选择行改变信号
     * @param rowId 行id
     */
    void selectRowChangeSignal(const QVariant &rowId);
    /**
     * @brief selectCellChangeSignal 选择单元格改变信号
     * @param rowId
     * @param columnIndex
     */
    void selectCellChangeSignal(const QVariant &rowId,const int columnIndex);
    /**
     * @brief sgl_CellValueChangeSignal 单元格值改变信号
     * @param rowId 行号
     * @param columnIndex 列索引
     * @param value 单元格改变后的值
     * @return 成功/失败
     */
    bool sgl_CellValueChangeSignal(const QVariant &rowId, const int columnIndex, const QVariant &value);

protected slots:
    /**
     * @brief dataChangedSlot 单元格内容改变
     * @param topLeft
     * @param bottomRight
     * @param roles
     */
    void dataChangedSlot(QStandardItem *item);

protected:
    /**
     * @brief mousePressEvent 鼠标事件
     * @param event 事件指针
     */
    void mousePressEvent(QMouseEvent *event) override;
};
#endif // GY_IDTABLEVIEW_H
